#include <iostream>
#include <fstream>
#include "contacts.pb.h"

void PrintContacts(contacts::Contacts contact)
{
    for(int i = 0;i < contact.contacts_size();i++)
    {
        std::cout << "------------------------  联系人" <<  i + 1 << "  ------------------------" << std::endl;
        const contacts::PeopleInfo people = contact.contacts(i);
        std::cout << "联系人姓名：" << people.name() << std::endl;
        std::cout << "联系人年龄：" << people.age() << std::endl;
        for(int j = 0;j < people.phone_size();j++)
        {
            const contacts::PeopleInfo_Phone phone = people.phone(j);
            std::cout << "联系人" << j + 1 << "电话：" << phone.number() << "   (" << phone.PhoneType_Name(phone.type()) << ")   " << std::endl; 
        }

        // 判断是否有这个类型数据且是否是Address消息体
        if(people.has_address() && people.address().Is<contacts::Address>())
        {
            contacts::Address address;
            // unpackto反序列化Any类型
            // 将address变量传入，返回时带回Any类型反序列化后的数据
            people.address().UnpackTo(&address);
            
            // 为空说明数据反序列化失败，或者未传输数据
            if(!address.home_address().empty())
                std::cout << "联系人家庭地址：" << address.home_address() << std::endl;

            if(!address.unit_address().empty())
                std::cout << "联系人单位地址：" << address.unit_address() << std::endl;
        }

        // people.one_contacts_case(): 返回的是oneof中的序号，这便可证明哪个被使用了
        switch (people.one_contacts_case())
        {
        case contacts::PeopleInfo::kQq:
            std::cout << "联系人QQ: " << people.qq() << std::endl;
            break;
        case contacts::PeopleInfo::kWechat:
            std::cout << "联系人WeChat: " << people.wechat() << std::endl;
            break;
        
        default:
            break;
        }

        if(people.remark_size())
            std::cout << "备注信息: " << std::endl;

        for(auto it = people.remark().begin();it != people.remark().end();it++){
            std::cout << "  " << it->first << ": " << it->second << std::endl;
        }
    }
}
int main()
{
    // 1. 读取文件中的数据
    contacts::Contacts contact;
    std::fstream input("contacts.bin",std::ios::in | std::ios::binary);
    // 获取数据到contact，并反序列化数据
    if(!contact.ParseFromIstream(&input))
    {
        std::cerr << "文件读取失败" << std::endl;
        input.close();
        return -1;
    }

    // 2. 打印数据
    PrintContacts(contact);
    input.close();
}